package vv.lines.core;

import vv.lines.core.context.IContext;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author vpotapenko
 */
public class BallHolder {

    private Ball selectedBall;
    private Random rand = new Random();

    private Map<BallBufferType, BallBuffer> buffers = new HashMap<BallBufferType, BallBuffer>();

    public BallHolder() {
        initBuffers();
    }

    private void initBuffers() {
        buffers.put(BallBufferType.PRIMARY, new BallBuffer());
        buffers.put(BallBufferType.DELETED, new BallBuffer());
        buffers.put(BallBufferType.GENERATED, new BallBuffer());
    }

    public BallBuffer primaryBuffer() {
        return buffers.get(BallBufferType.PRIMARY);
    }

    public BallBuffer generatedBuffer() {
        return buffers.get(BallBufferType.GENERATED);
    }

    public BallBuffer deletedBuffer() {
        return buffers.get(BallBufferType.DELETED);
    }

    public void clearAll() {
        deletedBuffer().clear();
        generatedBuffer().clear();

        deletedBuffer().add(primaryBuffer().asList());
        doRemove();

        selectedBall = null;
    }

    public void doRemove() {
        for (Ball ball : deletedBuffer()) {
            ball.setField(null);
            ball.setVisible(false);
        }
        deletedBuffer().clear();
    }

    public void removeBall(Ball ball) {
        if (ball == null) return;

        if (ball == selectedBall) setSelectedBall(null);

        primaryBuffer().remove(ball);
        deletedBuffer().add(ball);
    }

    public Ball getSelectedBall() {
        return selectedBall;
    }

    public void setSelectedBall(Ball selectedBall) {
        this.selectedBall = selectedBall;
    }

    private void generateBall(IContext context) {
        final int value = rand.nextInt(context.getMaxValue()) + 1;
        Ball ball = new Ball(context, value);

        primaryBuffer().add(ball);
        generatedBuffer().add(ball);
    }

    public void generateNewBalls(IContext context) {
        for (int i = 0; i < context.getGenerateCount(); i++)
            generateBall(context);
    }

    public Ball peekGeneratedBall(IContext context) {
        if (generatedBuffer().isEmpty()) generateNewBalls(context);

        Ball ball = generatedBuffer().remove(0);
        generatedBuffer().add(ball);

        return ball;
    }
}
